/*
 * Platzad
 * Copyright 2008 Shayne Riley
 *
 * This file is part of Platzad.
 *
 * Platzad is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Platzad is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Platzad.  If not, see <http://www.gnu.org/licenses/>.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <shayner at gmail dot com> or write to
 * Shayne Riley / P.O. Box 1092 / McCook, NE 69001.
 */

#ifndef SDLDELEGATE_H_
#define SDLDELEGATE_H_

#include <SDL/SDL.h>

namespace pzd {

//! Performs the required SDL back-end tasks when a sub-system initializes.
/**
 * A sub-system should not require any other sub-system to be initialized
 * prior to itself being initialized. However, complications may arise because
 * of this:
 * - SDL_Init(SDL_INIT_VIDEO) should be called first, before other SDL aspects
 * can be used, like audio.
 * - A window must be created if controls are to be captured.
 *
 * These two realms *could* be handled directly by the DisplaySystem, however
 * that would require that the other sub-systems must check to see if
 * DisplaySystem was started, or start it themselves, which goes against the
 * philosophy that no sub-system can know about the other sub-systems. By
 * moving portions of SDL initialization to this class, the sub-systems can
 * activate only the basic parts of SDL that are required, but will not
 * interfere with the operations of the other sub-systems.
 */
class SDLDelegate
{
    public:
    	/**
    	 * Retrieves the only instance of this class.
    	 * @returns the only instance of this class.
    	 */
    	static SDLDelegate& getInstance();

    	/**
    	 * Initialize SDL (if not already).
    	 * @returns true for successful initialization of the core of SDL
    	 * (or if SDL was initialized previously) or false if not.
    	 */
    	bool needSDL();

    	/**
    	 * Initialize SDL (if not already) and initialize the window.
    	 * @returns true for successful initialization of the core of SDL and
    	 * window (or if SDL and window were initialized previously),
    	 * or false if not.
    	 */
    	bool needSDLWithWindow();

    	/*
    	 * There may be a need for more functions. Examples:
    	 * - Display System may need to take over the basic window that was
    	 * created.
    	 * - If DisplaySystem was initialized first (like it should be),
    	 * then a way is needed of notifying SDLDelegate.
    	 */
    private:
    	//! Constructor for the delegate.
    	/**
    	 * There should only be one delegate. Making the constructor private
    	 * ensures this happens.
    	 */
        SDLDelegate();

        //! Destructor for a class that will never be derived from.
        ~SDLDelegate();

        //! Cleans up what has been created.
        void finalize();

        //! No copying needed, do not allow. Copy ctor declared, not defined.
        //! @param rhs	Right-Hand Side reference not used.
        SDLDelegate(const SDLDelegate& rhs);
        //! No assignment needed. Do not define this function.
        //! @param rhs	Right-Hand Side reference not used.
        SDLDelegate& operator=(const SDLDelegate rhs);
        //! No address-of needed. Do not define this function.
        SDLDelegate* operator&();
        //! No const address-of needed. Do not define this function.
        const SDLDelegate* operator&() const;
};

} // namespace

#endif /*SDLDELEGATE_H_*/
